package com.demo.crm.springboot3security.security;

import lombok.extern.slf4j.Slf4j;
import org.springframework.security.authorization.AuthorizationDecision;
import org.springframework.security.authorization.AuthorizationManager;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.web.access.intercept.RequestAuthorizationContext;
import org.springframework.stereotype.Component;

import java.util.Set;
import java.util.function.Supplier;
import java.util.stream.Collectors;

/**
 * 自定义授权管理器
 * 使用Spring Security 6的新授权API实现动态权限控制
 */
@Slf4j
@Component
public class CustomAccessDecisionManager implements AuthorizationManager<RequestAuthorizationContext> {

    /**
     * 检查是否授权访问
     * @param authentication 认证信息供应商
     * @param context 请求上下文
     * @return 授权决定
     */
    @Override
    public AuthorizationDecision check(Supplier<Authentication> authentication, RequestAuthorizationContext context) {
        Authentication auth = authentication.get();
        log.debug("Checking authorization for authentication: {}", auth);

        // 如果没有认证信息，拒绝访问
        if (auth == null || !auth.isAuthenticated()) {
            log.debug("Access denied - No authentication or not authenticated");
            return new AuthorizationDecision(false);
        }

        // 获取请求信息
        String requestUrl = context.getRequest().getRequestURI();
        String requestMethod = context.getRequest().getMethod();
        log.debug("Request URL: {}, Method: {}", requestUrl, requestMethod);

        // 获取当前用户的所有权限
        Set<String> userAuthorities = auth.getAuthorities().stream()
                .map(GrantedAuthority::getAuthority)
                .collect(Collectors.toSet());
        log.debug("User authorities: {}", userAuthorities);

        // 如果是超级管理员角色，直接允许访问
//        if (userAuthorities.contains("ROLE_ADMIN")) {
//            log.debug("Access granted - User has ROLE_ADMIN");
//            return new AuthorizationDecision(true);
//        }

        // 如果用户已认证且请求的是公开资源，允许访问
        if (isPublicResource(requestUrl)) {
            log.debug("Access granted - Public resource");
            return new AuthorizationDecision(true);
        }

        // 检查用户是否拥有所需权限
        boolean hasPermission = userAuthorities.stream()
                .anyMatch(authority -> matchesPermission(authority, requestUrl, requestMethod));

        log.debug("Access decision for URL: {}, Method: {}, HasPermission: {}", 
                 requestUrl, requestMethod, hasPermission);

        return new AuthorizationDecision(hasPermission);
    }

    /**
     * 判断是否是公开资源
     */
    private boolean isPublicResource(String url) {
        return url.startsWith("/api/auth/") || 
               url.equals("/error") || 
               url.equals("/test");
    }

    /**
     * 检查权限是否匹配
     */
    private boolean matchesPermission(String authority, String url, String method) {
        // 如果只需要登录验证
        if ("ROLE_USER_ADMIN".equals(authority)) {
            return true;
        }

        // 构建权限键
        String permissionKey = String.format("%s:%s", url, method).toLowerCase();
        String authorityKey = authority.toLowerCase();

        // 检查URL模式匹配
        if (url.startsWith("/api/users") && authorityKey.startsWith("user:")) {
            return true;
        }
        if (url.startsWith("/api/roles") && authorityKey.startsWith("role:")) {
            return true;
        }
        if (url.startsWith("/api/basic") && authorityKey.startsWith("basic:")) {
            return true;
        }

        return false;
    }
} 